package org.example.spring.simple.framework.aop.aspect;

import java.lang.reflect.Method;

/**
 * 使用模板模式设计
 * 封装拦截器回调的 通用逻辑，主要封装反射动态调用方法，其子类只需要控制调用顺序即可。
 */
public abstract class ZAbstractAspectJAdvice implements ZAdvice {
    private Method aspectMethod;
    private Object aspectTarget;

    public ZAbstractAspectJAdvice(Method aspectMethod, Object aspectTarget) {
        this.aspectMethod = aspectMethod;
        this.aspectTarget = aspectTarget;
    }

    protected Object invokeAdviceMethod(ZJoinPoint joinPoint, Object returnValue, Throwable e) throws Throwable {
        Class<?>[] parameterTypes = this.aspectMethod.getParameterTypes();
        if (null == parameterTypes || parameterTypes.length == 0) {
            return this.aspectMethod.invoke(aspectTarget);
        } else {
            Object[] args = new Object[parameterTypes.length];
            for (int i = 0; i < args.length; i++) {
                if (parameterTypes[i] == ZJoinPoint.class) {
                    args[i] = joinPoint;
                }
                if (parameterTypes[i] == Throwable.class) {
                    args[i] = e;
                }
                if (parameterTypes[i] == Object.class) {
                    args[i] = returnValue;
                }
            }
            return this.aspectMethod.invoke(aspectTarget, args);
        }
    }
}
